package com.powerunion.datacollection.report.excelreport;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import com.powerunion.datacollection.config.ConfigUtil;
import com.powerunion.datacollection.report.excelreport.config.DataSourceConfig;
import com.powerunion.datacollection.report.excelreport.config.ReportConfig;
import com.powerunion.datacollection.report.excelreport.datasource.BaseDataSource;
import com.powerunion.datacollection.report.excelreport.datasource.DBConnection;
import com.powerunion.datacollection.web.struts.DataCollectViewAction;
import com.powerunion.extjs.utils.Path;
import com.powerunion.util.log.LogHelper;

public class ExcelReportFacade {

	private static final Logger log = LogHelper.getInstance().getLogger(
			ExcelReportFacade.class);
	
    public void init() throws ServletException {
    	String templetFilePath = ConfigUtil.getInstance().getParameter("excelreport.TempletFilePath");
    	String jndi = ConfigUtil.getInstance().getParameter("excelreport.TempletFilePath");
    	 this.path = templetFilePath;
    	 this.jndi = jndi;
        
    }

    /**
     * 设置报表参数
     * @param name：参数名称
     * @param value：参数值
     */
//    private void setReportParam(String name, String value){
//        if(name.equals("DSImplDataBase")){
//            getInstance(value,DataSourceConfig.DS_TYPE_DATABASE);
//        }else if( name.equals("DSImplStatic")){
//            getInstance(value,DataSourceConfig.DS_TYPE_STATIC);
//        }else if(name.equals("TempletFilePath")){
//            path = value;
//        }else if(name.equals("JNDI")){
//            jndi = value;
//        }else if(name.equals("Logger")){
//            logger = value;
//        }
//    }
    
    /**
     * 处理报表打印请求。
     * @param request
     * @param response
     * @throws IOException
     */
    public boolean process(HttpServletRequest request, HttpServletResponse response,String reportName) throws IOException{
    	boolean flag=false;
    	String realPath = request.getSession().getServletContext().getRealPath("");
    	String xlsPath = realPath+"\\report\\xls\\";
    	
        //String reportName = (String)request.getParameter(ReportConfig.REPORT);
    
        String reloadConfig = (String)request.getParameter("reloadConfig");
        boolean needReloadConfig = false;
        if(null != reloadConfig && reloadConfig.equalsIgnoreCase("true")){
            needReloadConfig = true;
        }
        File file = new File(xlsPath+reportName+".xls");
        file.createNewFile();
        file.mkdir();
        if(file.isFile()){
        	System.out.println("是File......");
        }else{
        	System.out.println("不是File......");
        }
        FileOutputStream os = new FileOutputStream(file,true);
        try{

            long curTime = System.currentTimeMillis();
            ReportEngine r = getReportEngine(needReloadConfig);
            //取得报表参数
            Map params = getParamMap(request);
            //生成报表
            r.getReportAsExcel(os, params);
            os.flush();
            log.debug("Total time:" + String.valueOf(System.currentTimeMillis() - curTime) + " milliseconds");
            
            //response.flushBuffer();
            flag = true;
        }catch(Exception e){
            log.error(e.getMessage(), e);
            response.setContentType("text/html");
            response.setHeader("Content-Encoding","gb2312");
            
            PrintWriter buf = new PrintWriter(os);
            buf.println("<HTML>");
            buf.println("<HEAD><TITLE>Excel Report debug</TITLE></HEAD>");
            buf.println("<BODY>");
            buf.println("<b>异常信息：</b><br>");
            buf.println(e.getMessage());
            buf.println("</BODY></HTML>");
            os.flush();
            
        }finally{
        	if(os != null){
        		os.close();
        		os = null;
        	}
        }
        return flag;
    }
    
    /**
     * 根据Repuest来生成报表需要的参数信息。
     * @param request: HttpServletRequest对象，保存用户请求的信息。
     * @return 参数包装Map,该Map对象以报表生成器需要的格式封装用户请求的参数信息。
     */
    protected Map getParamMap(HttpServletRequest request){
        Enumeration params = request.getParameterNames();
        String param = null;
        String value = "";
        String [] values = null;
        Map retMap = new HashMap();
        while(params.hasMoreElements()){
            param = (String)params.nextElement();
            value = (String)request.getParameter(param);
            retMap.put(param, value);
        }
        
        retMap.put("request", request);
        return retMap;
    }
    
    private ReportEngine reportEngine = null;
    /**
     * 取得报表引擎对象，报表引擎对象在应用中只有一个实例存在。
     * @param reload：标识是否需要强制重新装载报表配置信息。<br>
     * true：重新装载。
     * false：不需重新装载。
     * @return 返回报表引擎对象。
     */
    protected synchronized ReportEngine getReportEngine(boolean reload){
        if(null != reportEngine && !reload){
            return reportEngine;
        }
        String path = Path.getFullPathRelateClass("../../../../..", ExcelReportFacade.class);
        
        //设置报表logger实现类
        if(null  != logger){
            ReportEngine.setLogger(logger);
        }
        String configPath = path + File.separator +"ReportConfig"+File.separator + "ReportConfig.xml";
        //取得报表管理对象
        reportEngine = ReportEngine.getReportEngine(configPath,
                reload);
        
        //设置报表模板文件目录 
        reportEngine.setTempletFilePath(path);
        
        //设置数据连接属性
        if(null != this.jndi){
            reportEngine.setDBConnection(new DBConnection(jndi));
        }
        
        //设置数据源实现类。
        Object obj = null;
        if(null != dsImpl){
            obj = dsImpl.get(DataSourceConfig.DS_TYPE_DATABASE);
            if(null != obj){
                reportEngine.setDataSourceImplement(DataSourceConfig.DS_TYPE_DATABASE, 
                        (BaseDataSource)obj);
            }
            
            obj = null;
            if(null != (obj = dsImpl.get(DataSourceConfig.DS_TYPE_STATIC))){
                reportEngine.setDataSourceImplement(DataSourceConfig.DS_TYPE_STATIC, 
                        (BaseDataSource)obj);
            }
        }
        return reportEngine;
    }
    
    /**
     * 取得用户配置数据源类的实例。
     * @param className：要生成实例的class名称。
     * @param dsType：标识数据源的类型。
     * @return 返回生成的数据源对象。
     */
    private Object getInstance(String className, String dsType){
        Object obj = null;
        try{
            if(log.isDebugEnabled()){
                log.debug("Excel report initializing: Create data source instance:" + className);
            }
            ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
            if (classLoader == null) {
                classLoader = ExcelReportServlet.class.getClassLoader();
            }
            
            obj = classLoader.loadClass(className).newInstance();
            if(null != obj && obj instanceof BaseDataSource){
                if(null == dsImpl){
                    dsImpl = new HashMap();
                }
                dsImpl.put(dsType, obj);
                return obj;
            }
            
            log.error("User defined data source must inherited from excel.report.datasource.BaseDataSource.");
        }catch(Exception e){
            log.error("Catched an Exception when loads a datasource instance. --" 
                    + className
                    + " \n " + e.getMessage(), e);
            
        }
        return null;
    }
    
    protected Map dsImpl = null;
    protected String path = "/WEB-INF/classes/ReportConfig";
    protected String jndi = null;
    protected String logger = null;
}
